package com.wm.blog_common.util.excel;

import com.wm.blog_common.enums.DownloadTypeEnum;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFHyperlink;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CountDownLatch;

/**
 * @class_name: PoiExcelTask
 * @description:  excel操作消费线程
 * @author: 半卷流年
 * @create: 2019/09/02
 **/
public class PoiExcelTask implements Runnable{

    private final static Logger log = LoggerFactory.getLogger(PoiExcelTask.class);

    private Sheet sheet;
    private Workbook workbook;
    private List<?> dataList;
    private List<Field> fields;
    private int rowIndex;
    private CreationHelper createHelper;
    private  Map<String,String> linkMap;
    private CellStyle cellStyle;
    private CountDownLatch latch;

    private Drawing patriarch;


    public PoiExcelTask(Sheet sheet, Workbook workbook, List<?> dataList, List<Field> fields, int rowIndex, CreationHelper createHelper, Map<String, String> linkMap, CellStyle cellStyle, CountDownLatch latch,Drawing patriarch) {
        this.sheet = sheet;
        this.workbook = workbook;
        this.dataList = dataList;
        this.fields = fields;
        this.rowIndex = rowIndex;
        this.createHelper = createHelper;
        this.linkMap = linkMap;
        this.cellStyle = cellStyle;
        this.latch = latch;
        this.patriarch = patriarch;
    }

    /**
     * 获取行,加锁
     * @param sheet
     * @param rowIndex
     * @return
     */
    private static Row getRow(Sheet sheet,int rowIndex){
        synchronized (Object.class) {
            return sheet.createRow(rowIndex);
        }
    }

    @Override
    public void run() {
            // 遍历集合数据，产生数据行
            try {
                int index = rowIndex;
                for (Object obj : dataList) {
                    Row rowData = getRow(sheet,index);
                    for (int i = 0; i < fields.size(); i++) {
                        Cell newCell = rowData.createCell(i);
                        Field field = fields.get(i);
                        field.setAccessible(true);
                        Object fieldValue = null;
                        //判断是否是图片,根据注解,如果是图片,则插入图片,进行下面的操作
                        try {
                            fieldValue = field.get(obj);
                        } catch (IllegalAccessException e) {
                            log.error("excel thread error .... {}",e.getMessage(),e);
                        }
                        String fieldValueString = FieldReflectionUtil.formatValue(field, fieldValue);
                        boolean imageFlag = field.getAnnotation(ExcelField.class).isImage();
                        if(imageFlag){
                            //图片下载方式,如果是本地的图片
                            int downloadType = field.getAnnotation(ExcelField.class).downloadType();
                            if(downloadType == DownloadTypeEnum.LOCAL.getValue()){
                                try {
                                    //得到图片的二进制数据，以二进制封装得到数据，具有通用性
                                    InputStream inputStream = new FileInputStream(fieldValueString);
                                    byte[] bytes = IOUtils.toByteArray(inputStream);
                                    /**anchor主要用于设置图片的属性
                                     * 该构造函数有8个参数
                                     * 前四个参数是控制图片在单元格的位置，分别是图片距离单元格left，top，right，bottom的像素距离
                                     * 后四个参数，前两个表示图片左上角所在的cellNum和 rowNum，后两个参数对应的表示图片右下角所在的cellNum和 rowNum，
                                     * excel中的cellNum和rowNum的index都是从0开始的
                                     */
                                    //设置图片在单元格中的位置
                                    int d = 255;
                                    XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, d, d, (short)i, index , (short) i + 1,index + 1);
                                    //Sets the anchor type （图片在单元格的位置）   //0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
                                    anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);
                                    patriarch.createPicture(anchor, workbook.addPicture(bytes, XSSFWorkbook.PICTURE_TYPE_JPEG));
                                }catch (Exception e){
                                    log.error("thread write image to excel error ... {}",e.getMessage(),e);
                                }
                            }else{
                                //todo http请求获取图片数据,如下载阿里云/七牛云等图片资源
                            }

                        }else{
                            if (fieldValueString.startsWith("http://") || fieldValueString.startsWith("https://")) {
                                CellStyle linkCellStyle = workbook.createCellStyle();
                                linkCellStyle.cloneStyleFrom(cellStyle);
                                Font linkCellFont = workbook.createFont();
                                linkCellFont.setUnderline((byte) 1);
                                linkCellFont.setColor(HSSFColor.BLUE.index);
                                linkCellFont.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
                                linkCellStyle.setFont(linkCellFont);
                                newCell.setCellStyle(linkCellStyle);
                                XSSFHyperlink hyperLink = (XSSFHyperlink) createHelper.createHyperlink(Hyperlink.LINK_URL);
                                hyperLink.setAddress(fieldValueString);
                                newCell.setHyperlink(hyperLink);
                                newCell.setCellValue(linkMap != null ? linkMap.get(field.getName()) : "点击此处链接");
                            } else {
                                newCell.setCellValue(fieldValueString);
                                newCell.setCellStyle(cellStyle);
                            }
                        }
                    }
                    index ++;
                }
            } catch (Exception e) {
                log.error("填充excel行数据异常:{}",e.getMessage(),e);
            } finally {
                Optional.ofNullable(latch).ifPresent(CountDownLatch::countDown);
            }
        }
}
